#pragma once
#include <iostream>
#include <pthread.h>
#include <vector>
#include <queue>
#include <cstring>
#include <functional>
#include <string>
#include "Log.hpp"
#include "LockGuard.hpp"
#include "Thread.hpp"
#include "Task.hpp"
using namespace std;

struct ThreadData {
    ThreadData(const string& threadname) 
        :_threadname(threadname)
    {}
    ~ThreadData() {

    }
    string _threadname;
};
const int defaultnum = 10;



template <class T>
class ThreadPool {
    public :
    // 构造函数
    ThreadPool(const int thread_num = defaultnum) 
        :_thread_num(thread_num)
    {
        // 初始化锁和条件变量
        pthread_mutex_init(&_mutex, nullptr);
        pthread_cond_init(&_cond, nullptr);
        // 创建线程
        for (int i = 0; i < _thread_num; i++) {
            string threadname = "thread-" + to_string(i + 1);
            ThreadData td(threadname);
            // thread<ThreadData> t(threadname, bind(&ThreadPool<T>::ThreadRun, this, placeholders::_1), td);
            // _threads.push_back(t);
            // 减少拷贝的版本
            _threads.emplace_back(threadname, bind(&ThreadPool<T>::ThreadRun, this, placeholders::_1), td);
            lg.LogMessage(Info, "%s is created……", threadname.c_str());
        }
    }

    // 启动线程
    void Start() {
        for (auto& Thread : _threads) {
            Thread.Start();
            lg.LogMessage(Info, "%s is start……", Thread.get_name().c_str());
        }
    }

    // 向队列中添加任务
    void Push(T& in) {
        LockGuard lock(&_mutex);
        _q.push(in);
        lg.LogMessage(Info, "push a Task: %s", in.TaskToString().c_str());
        // 唤醒一个线程
        pthread_cond_signal(&_cond);
    }

    void ThreadRun(ThreadData& td) {
        while (true) {
            // 拿任务
            T t;
            {
                // 先加锁
                LockGuard lock(&_mutex);
                while (_q.empty()) {
                    pthread_cond_wait(&_cond, &_mutex);
                }

                t = _q.front();
                _q.pop();   

            }

            // 处理任务
            t();
            lg.LogMessage(Debug, "%s handle done a Task : %s, result is : %s", td._threadname.c_str(), t.TaskToString().c_str(),\
            t.ResultToString().c_str());
            // cout << td._threadname << " get a Task : " << t.ResultToString() << endl;
        }


    }

    // 析构函数
    ~ThreadPool() {
        // 销毁锁和条件变量
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond);
        for (auto& thread : _threads) {
            thread.Join();
        }
        cout << "~ThreadPool()" << endl;
    }
    private :
    queue<T> _q; // 任务队列
    vector<thread<ThreadData>> _threads; // 线程集合
    int _thread_num;
    pthread_mutex_t _mutex; // 线程互斥锁
    pthread_cond_t _cond; // 条件变量
};

// static const int defaultnum = 10;
// class ThreadData {

// };

// template <class T, class V>
// class ThreadPool {
//     public :
//     ThreadPool(const int thread_num = defaultnum)
//         :_thread_num(thread_num)
//     {
//         // 初始化锁和条件变量
//         pthread_mutex_init(&_mutex, nullptr);
//         pthread_cond_init(&_cond, nullptr);
//         // 创建出指定数量的线程
//         for (int i = 0; i < _thread_num; i++) {
//             string threadname = "thread";
//             threadname += to_string(i + 1);

//             ThreadData td;
//             Thread<ThreadData, string> t(threadname,
//              bind(&ThreadPool<T, V>::TreadRun, this, placeholders::_1, placeholders::_2), td);
//             _threads.push_back(t);
//         }

//     }

//     bool Start() {
//         // 启动线程
//         for (auto& thread : _threads) {
//             thread.Start();
//         }


//     }

//     void TreadRun(ThreadData &td) {
//         while (true) {
//             cout << "thread is running……" << endl;
//             sleep(1);
//         }
//     }

//     void Push(const T& in) {

//     }




//     ~ThreadPool() {
//         // 销毁锁和条件变量
//         pthread_mutex_destroy(&_mutex);
//         pthread_cond_destroy(&_cond);
//         for (auto& thread : _threads) {
//             thread.Join();
//         }

//     }
//     private :
//     queue<T> _q; // 任务队列
//     vector<Thread<ThreadData, string>> _threads; // 线程集合
//     int _thread_num; // 多少个线程
//     pthread_mutex_t _mutex; // 线程互斥锁
//     pthread_cond_t _cond; // 条件变量
// };